from flask import Flask, render_template, request, url_for, redirect, session, flash
from flask_sqlalchemy import SQLAlchemy
from werkzeug.security import generate_password_hash, check_password_hash
from datetime import datetime
from sqlalchemy.exc import IntegrityError

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:tangfamily123@localhost/blog'
app.config['SECRET_KEY'] = 'your-secret-key'  # 设置你的秘密密钥
db = SQLAlchemy(app)

@app.template_filter('get_user_name')
def get_user_name(user_id):
    user = User.query.get(user_id)
    if user:
        return user.UserName
    return ''


class User(db.Model):
    UserID = db.Column(db.Integer, primary_key=True, autoincrement=True)
    UserName = db.Column(db.String(255), unique=True, nullable=False)
    UserPassword = db.Column(db.String(255), nullable=False)
    UserType = db.Column(db.Enum('Student', 'Teacher'), nullable=False)

class Comment(db.Model):
    CommentID = db.Column(db.Integer, primary_key=True, autoincrement=True)
    CommentContent = db.Column(db.String(255), nullable=False)
    UserID = db.Column(db.Integer, db.ForeignKey('user.UserID'), nullable=False)
    Timestamp = db.Column(db.DateTime, default=datetime.utcnow)

class Course(db.Model):
    CourseID = db.Column(db.Integer, primary_key=True, autoincrement=True)
    CourseName = db.Column(db.String(255), nullable=False)
    TeacherID = db.Column(db.Integer, db.ForeignKey('user.UserID'))
    CourseCapacity = db.Column(db.Integer, nullable=True)
    teacher = db.relationship('User', backref=db.backref('courses_taught', lazy=True))

class Enrollment(db.Model):
    EnrollmentID = db.Column(db.Integer, primary_key=True, autoincrement=True)
    StudentID = db.Column(db.Integer, db.ForeignKey('user.UserID'))
    CourseID = db.Column(db.Integer, db.ForeignKey('course.CourseID'))
    Grade = db.Column(db.Integer)
    course = db.relationship('Course', backref=db.backref('enrollments', cascade='all, delete'))
    student = db.relationship('User', backref=db.backref('enrollments', cascade='all, delete'))

class CourseInfo(db.Model):
    __tablename__ = 'CourseInfo'
    CourseID = db.Column(db.Integer, primary_key=True)
    StudentID = db.Column(db.Integer, primary_key=True)
    StudentName = db.Column(db.String(255))
    Grade = db.Column(db.Integer)

    
@app.route('/')
def home():
    return render_template('home.html')

@app.route('/register', methods=['GET', 'POST'])
def register():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        usertype = request.form['usertype']
       # password_hash = generate_password_hash(password)

        try:
            new_user = User(UserName=username, UserPassword=password, UserType=usertype)
            db.session.add(new_user)
            db.session.commit()
            flash('User registered successfully!')
            return redirect(url_for('login'))
        except IntegrityError:
            db.session.rollback()
            error_msg = 'Username already exists.'
            flash(error_msg)
            return render_template('register.html')
    return render_template('register.html')

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        user = User.query.filter_by(UserName=username).first()
        if user and user.UserPassword==password:
            session['user_id'] = user.UserID
            session['user_type'] = user.UserType
            return redirect(url_for('profile'))
        else:
            flash('Incorrect username or password.')
            return render_template('login.html')
    return render_template('login.html')

@app.route('/profile')
def profile():
    user_id = session.get('user_id')
    if not user_id:
        return redirect(url_for('login'))
    user = User.query.get(user_id)
    if not user:
        return redirect(url_for('login'))

    if user.UserType == 'Student':
        enrollments = Enrollment.query.filter_by(StudentID=user_id).all()
        courses = [enrollment.course for enrollment in enrollments]
        comments = Comment.query.order_by(Comment.Timestamp.desc()).all()  # 获取所有评论，并按时间倒序排列
        return render_template('student_profile.html', user=user, courses=courses, comments=comments)
    elif user.UserType == 'Teacher':
        courses = Course.query.filter_by(TeacherID=user_id).all()
        comments = Comment.query.order_by(Comment.Timestamp.desc()).all()  # 获取所有评论，并按时间倒序排列
        return render_template('teacher_profile.html', user=user, courses=courses, comments=comments)
    return "Invalid user type"


@app.route('/create_course', methods=['GET', 'POST'])
def create_course():
    if request.method == 'POST':
        course_name = request.form['course_name']
        course_capacity = request.form.get('course_capacity')
        user_id = session.get('user_id')
        if not user_id:
            return redirect(url_for('login'))
        user = User.query.get(user_id)
        if user.UserType != 'Teacher':
            flash('You do not have permission to create a course')
            return redirect(url_for('courses'))
        new_course = Course(CourseName=course_name, TeacherID=user_id, CourseCapacity=course_capacity)
        db.session.add(new_course)
        db.session.commit()
        return redirect(url_for('profile'))
    return render_template('create_course.html')

@app.route('/courses')
def courses():
    user_id = session.get('user_id')
    if not user_id:
        return redirect(url_for('login'))
    courses = Course.query.all()
    return render_template('courses.html', courses=courses)


@app.route('/enroll_course/<int:course_id>', methods=['POST'])
def enroll_course(course_id):
    course = Course.query.get(course_id)
    user_id = session.get('user_id')
    if not user_id:
        return redirect(url_for('login'))
    user = User.query.get(user_id)
    if user.UserType != 'Student':
        flash('You do not have permission to enroll in a course')
        return redirect(url_for('courses'))
    if course.CourseCapacity is not None and course.CourseCapacity <= 0:
        flash('The course is full, you cannot enroll')
        return redirect(url_for('courses'))
    enrollment = Enrollment.query.filter_by(StudentID=user_id, CourseID=course_id).first()
    if enrollment:
        flash('You have already enrolled in this course.')
        return redirect(url_for('courses'))
    
    try:
        new_enrollment = Enrollment(StudentID=user_id, CourseID=course_id)
        db.session.add(new_enrollment)

        # 获取学生的用户名
        student_name = user.UserName
        
        new_course_info = CourseInfo(CourseID=course_id, StudentID=user_id, StudentName=student_name, Grade=None)
        db.session.add(new_course_info)
        
        if course.CourseCapacity is not None:
            course.CourseCapacity -= 1  # 减少课程容量
        
        db.session.commit()
        flash('You have successfully enrolled in the course')
    except Exception as e:
        db.session.rollback()
        flash('Enrollment failed: ' + str(e))
    return redirect(url_for('courses'))



@app.route('/my_grades')
def my_grades():
    user_id = session.get('user_id')
    if not user_id:
        return redirect(url_for('login'))
    enrollments = Enrollment.query.filter_by(StudentID=user_id).all()
    return render_template('my_grades.html', enrollments=enrollments)


@app.route('/grade_students', methods=['GET', 'POST'])
def grade_students():
    user_id = session.get('user_id')
    user = User.query.get(user_id)

    if user.UserType == 'Teacher':
        # 获取老师教授的课程
        courses = Course.query.filter_by(TeacherID=user_id).all()

        if request.method == 'POST':
            # 处理打分逻辑
            course_id = request.form.get('course')
            # 遍历课程下的学生列表，并获取每个学生的成绩
            for course in courses:
                if str(course.CourseID) == course_id:  # Only process the selected course
                    for enrollment in course.enrollments:
                        grade_key = f"grade-{enrollment.StudentID}"
                        student_grade = request.form.get(grade_key)
                        # 检查学生成绩字段是否为空
                        if student_grade.strip():  # 如果成绩字段不为空
                            try:
                                # 更新成绩记录
                                enrollment.Grade = float(student_grade)
                                # 更新CourseInfo表中的成绩
                                course_info = CourseInfo.query.filter_by(CourseID=course.CourseID, StudentID=enrollment.StudentID).first()
                                if course_info:
                                    course_info.Grade = enrollment.Grade
                            except ValueError:
                                flash(f"Invalid grade value for student {enrollment.student.UserName}. Grade must be a valid number.")
            db.session.commit()
            flash('Grades have been submitted successfully.')
            return redirect(url_for('profile'))
        else:
            return render_template('grade_students.html', courses=courses)

    else:
        flash('You do not have permission to access this page.')
        return redirect(url_for('profile'))





@app.route('/comment', methods=['POST'])
def comment():
    user_id = session.get('user_id')
    if not user_id:
        return redirect(url_for('login'))
    content = request.form['content']
    new_comment = Comment(CommentContent=content, UserID=user_id, Timestamp=datetime.utcnow())
    db.session.add(new_comment)
    db.session.commit()
    flash('Comment submitted successfully!')
    return redirect(url_for('comments'))


@app.route('/comments')
def comments():
    user_id = session.get('user_id')
    if not user_id:
        return redirect(url_for('login'))
    all_comments = Comment.query.order_by(Comment.Timestamp.desc()).all()
    return render_template('comments.html', comments=all_comments)


@app.route('/withdraw/<int:course_id>', methods=['POST'])
def withdraw_course(course_id):
    try:
        db.session.begin()
        course = Course.query.get(course_id)
        if not course:
            raise Exception('Course not found.')
        user_id = session.get('user_id')
        enrollment = Enrollment.query.filter_by(StudentID=user_id, CourseID=course_id).first()
        if not enrollment:
            flash('You are not enrolled in this course.')
            return redirect(url_for('profile'))
        db.session.delete(enrollment)
        
        # 删除相应的 courseinfo 记录
        course_info = CourseInfo.query.filter_by(StudentID=user_id, CourseID=course_id).first()
        if course_info:
            db.session.delete(course_info)
            
        course.CourseCapacity += 1  # 增加课程容量
        db.session.commit()
        flash('Course withdrawal successful.')
        return redirect(url_for('profile'))
    except Exception as e:
        db.session.rollback()
        flash('Course withdrawal failed: ' + str(e))
        return redirect(url_for('profile'))


if __name__ == "__main__":
    with app.app_context():
        db.create_all()  # 在第一次运行时创建数据库表
    app.run(debug=True)
